<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="utf-8">
    <title>DOM测试</title>
    <script>
        function product(arr) {
            // FIXME:
            if (arr.length >= 2) {
                return arr.reduce((x, y) => x*y);
            } else if (arr.length === 1) {
                return arr[0];
            } else {
                return 0;
            }
        }
        console.log(product([1, 2]));

        // 测试:
        if (product([1, 2, 3, 4]) === 24 && product([0, 1, 2]) === 0 && product([99, 88, 77, 66]) === 44274384) {
            console.log('测试通过!');
        } else {
            console.log('测试失败!');
        }
    </script>
</head>
I'm between of HEAD and BODY.
<body>
test Start
<p id="demo" class="class1 class2">这是一个demo.</p>
<div id="div1" class="divClass">
    <p>这是第一段</p>
    <form>
        <label for="text1">输入文本：</label>
        <input type="text" id="text1" name="text1" placeholder="请输入文本">
    </form>
</div>
<ul id="ul"></ul>
<div id="target"></div>
"test" END
</body>
2
<script defer>
    let docfrag = document.createDocumentFragment();
    [1, 2, 3, 4].forEach(function (e) {
        let li = document.createElement('li');
        // li.textContent = e;
        // li.innerHTML = "<span>test</span>";
        let textnode = document.createTextNode("<span>\'test\'</span>");
        li.appendChild(textnode);
        docfrag.appendChild(li);
    });
    let element = document.getElementById('ul');
    element.appendChild(docfrag);

    function escapeHtml(str) {
        var div = document.createElement('div');
        // div.appendChild(document.createTextNode(str));
        div.nodeValue = str;
        return div.innerHTML;
    }
    var userWebsite = '" onmouseover="alert(\'derp\')" "';
    var profileLink = '<a href="' + escapeHtml(userWebsite) + '">Bob</a>';
    var div = document.getElementById('target');
    div.innerHTML = profileLink;
</script>
</html>
<script defer>
    console.log("一. 节点:")
    console.log("Node对象(浏览器原生提供,节点 是组成DOM的最小单位,对于HTML文档,任何东西都是节点)的类型目前有7种：");
    console.log(`0. document节点(文档节点是顶层节点,由浏览器原生提供)类型为:Node.DOCUMENT_NODE,值为9`);
    console.log(`document的节点类型:document.nodeType = ${document.nodeType}`);
    console.log(`0.0. document type节点(文档类型节点是1级节点,是文档节点的两个子节点之一: Node.DOCUMENT_TYPE_NODE,值为10`);
    console.log(`0.0. document type节点类型:Node.DOCUMENT_TYPE_NODE = ${document.childNodes[0].nodeType}`);
    console.log(`0.1. HTML节点即document节点的第二个子节点,(之所以叫它"root node",是因为它是网页的顶层容器.
    对于html文档来说,除了上面已经介绍的2个节点,其它节点都是它的子节点) ,它的类型为:Node.ELEMENT_NODE = ${document.childNodes[1].nodeType}`);
    console.log("通过下面这个循环可以得到所有document的所有直接子节点");
    for (let entry of document.childNodes.entries()) {
        console.log(entry[0] + ":nodeType:" + entry[1].nodeType + ",nodeName:" + entry[1].nodeName + ",nodeValue:" + entry[1].nodeValue);
    }

    console.log("-----------HTML节点(root node)------------------------------");

    console.log(`0.1.0. 对于HTML节点来说,也有2个子节点,分别是HEAD,BODY,这是显而易见的,它们的类型也是Node.ELEMENT_NODE(元素节点),也是通过上面的循环验证如下:`
        + `\n其实会发现不只是有2个,还多了几个,比如下而这样的:`
        + `\n但是有意思的是,你会发现第"1"个元素的nodeValue并不包含I'm between...`
        + `\n因为浏览器把这句话给放到BODY标签里了,nodeValue的值其实是2个字符,分别是1个换行符,1个制表符`);
    for (let entry of document.childNodes[1].childNodes.entries()) {
        console.log(entry[0] + ":nodeType:" + entry[1].nodeType + ",nodeName:" + entry[1].nodeName + ",nodeValue:" + entry[1].nodeValue);
    }

    console.log("-----------BODY节点----------------")
    console.log("其实我们平时大都是对BODY标签里的内容进行操作,所以在Node对象中专门有一个document.body,来返回BODY元素节点");
    for (let [index, item] of document.body.childNodes.entries()) {
        console.log(index + ":nodeType:" + item.nodeType + ",nodeName:" + item.nodeName + ",nodeValue:" + item.nodeValue);
    }

    console.log("----------元素节点(Node.ELEMENT_NODE)的属性节点(Node.ATTRIBUTE_NODE)---------");
    console.log("元素有属性,那么对应的就是属性节点,它是元素节点的子节点,P元素节点就有属性\"id\",示例如下:");
    // 先得到所有P元素节点,然后遍历打印出属性节点的信息
    let p_nodes = document.getElementsByTagName("p")
    console.log(p_nodes.length);
    for (let i = 0; i < p_nodes.length; i++) {
        console.log(`第 ${i} 个P元素信息如下:`);
        console.log("  nodType:" + p_nodes[i].nodeType + ", nodeName:" + p_nodes[i].nodeName);
        console.log("  textContent" + p_nodes[i].textContent);
        if (p_nodes[i].hasAttributes()) {
            let count = 0
            for (let entry of p_nodes[i].attributes) {
                console.log(` 第 ${count} 属性节点信息如下:`)
                console.log(`  节点名:${entry.nodeName},节点类型:${entry.nodeType},节点值:${entry.nodeValue}`);
                console.log(`  第 ${count} 属性节点包含的文本:${entry.textContent}`);
                count++;
            }
        }
        console.log("----------------------------");
    }

    let nodeType = document.nodeType;
    console.log(`document.nodeType: ${document.nodeType}`);
    console.log(`document.nodeName: ${document.nodeName}`);
    console.log(`document.nodeValue: ${document.nodeValue}`);

    let documentElement = document.documentElement;
    console.log("documentElement.nodeType:" + documentElement.nodeType);
    console.log("documentElement.nodeName:" + documentElement.nodeName);
    // console.log(documentElement.textContent);

    let nodeX = document.getElementById("text1");
    console.log("--------测试getRooNode方法--------")
    console.log(nodeX.getRootNode().nodeName);


    let node = document.documentElement.firstChild;
    console.log(`documentElement.firstChild.nodeType: ${node.nodeType}`);
    console.log(`documentElement.firstChild.nodeName: ${node.nodeName}`);
    console.log(`documentElement.firstChild.nodeValue: ${node.nodeValue}`);

    let elementNode = document.getElementById("div1");
    console.log("----------------------------")
    console.log("elementNode.nodeType: " + elementNode.nodeType);
    console.log("elementNode.nodeName: " + elementNode.nodeName);

    let children = document.childNodes[1].childNodes;  // document.getElementById("demo")
    console.log("------------测试2--------------");
    for (let entry of children.entries()) {
        console.log(entry[0] + ":nodeType:" + entry[1].nodeType + ",nodeName:" + entry[1].nodeName + ",nodeValue:" + entry[1].nodeValue);

    }

    console.log(document.getElementsByTagName("DIV").length);

    // ==================================================
    if (elementNode.hasAttribute("id")) {
        console.log("DIV节点有属性：id");
        let attNode = elementNode.getAttributeNode("id");
        console.log("id节点的类型：" + attNode.nodeType);

    }


    let nodChildren1 = document.getElementById('demo').childNodes;
    console.log("-------------测试孩子节点-----------");
    console.log("孩子节点共有：" + nodChildren1.length);

    for (let entry of nodChildren1.entries()) {
        console.log(entry[0] + ":nodeType:" + entry[1].nodeType + ",nodeName:" + entry[1].nodeName + ",nodeValue:" + entry[1].nodeValue);

    }

</script>
